#include <dretve.h>
#include <ispis.h>
#include <vrijeme.h>

static int mon, red[5];
static int stapic[5];
static char status[6];

void filozof(void *x)
{
	int i = (int) x;
	int L = (i+4)%5;
	int D = (i+1)%5;
	int n;
	vrijeme_t misli, jede;

	misli.sekunde = 1;
	misli.nsekunde = 0;
	jede.sekunde = 1;
	jede.nsekunde = 0;
	
	zakljucaj(mon);

	for (n = 0; n < 5; n++) { //ponavljam samo 5 puta
		//misli
		status[i] = 'O';
		ispisi("[%d]:%s\n", i, status);
		otkljucaj(mon);

		odgodi(misli);
		

		//jedi
		zakljucaj(mon);
		status[i] = 'o';
		ispisi("[%d]:%s\n", i, status);

		while (stapic[i] != 1 || stapic[D] != 1)
			cekaj_u_redu(red[i], mon);

		stapic[i] = stapic[D] = 0;
		status[i] = 'X';
		ispisi("[%d]:%s (%d)\n", i, status, n);
		otkljucaj(mon);

		odgodi(jede);

		//najeo se, vrati stapice
		zakljucaj(mon);
		stapic[i] = stapic[D] = 1;
		
		propusti_iz_reda(red[L]);
		propusti_iz_reda(red[D]);
		
	}
	status[i] = '-';
	ispisi("[%d]:%s\n", i, status);
	otkljucaj(mon);
}

void problem_filozofa()
{
	ispisi("\n[%s:%s]\n", __FILE__, __FUNCTION__);

	int dr[5], i;
	vrijeme_t koliko;
	koliko.sekunde = 1;
	koliko.nsekunde = 0;
	
	mon = dohvati_sinkro(MONITOR, 0, REKURZ | NASPRIO, 0);
	if (mon == -1) {
		ispisi("nema monitora!\n");
		return;
	}

	for (i = 0; i < 5; i++) {
		red[i] = dohvati_sinkro(REDUVJETA, 0, 0, 0);
		if (red[i] == -1) {
			ispisi("nema reda uvjeta!\n");
			goto prije_kraja;
		}
		stapic[i] = 1;
		status[i] = 'O';
	}
	
	for (i = 0; i < 5; i++) {
		dr[i] = stvori_dretvu(filozof, (void *) i);
		if (dr[i] == -1) {
			ispisi("Nisam stvorio dretvu!\n");
			goto prije_kraja;
		}
	}
	
prije_kraja:
	for (i = 0; i < 5; i++) {
		if (dr[i] != -1) {
			cekaj_kraj_dretve(dr[i]);
			ispisi("Docekana dretva %d!\n", dr[i]);
		}
	}

	//oslobodi monitor i redove
	obrisi_sinkro(mon);
	for (i = 0; i < 5; i++)
		obrisi_sinkro(red[i]);
}
